home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Toolbox / DefProcs / sbarcdef.a < prev    next >
Encoding:
Text File  |  1990-09-14  |  30.3 KB  |  954 lines  |  [TEXT/MPS ]

  1. ;EASE$$$ READ ONLY COPY of file “sbarcdef.a”
  2. ; 1.1    CCH 12/22/1988 Added bug fix to "FrameCtl:" from 6.0.4 sources.
  3. ; 1.0    CCH 11/16/1988 Added to EASE.
  4. ; END EASE MODIFICATION HISTORY 
  5. ;
  6. ;File SBarCDef.a
  7. ;--------------------------------------------------------------------------
  8. ;
  9. ;  Standard ScrollBar Dial Definition Procedure for the
  10. ;    MacIntosh Control Manager
  11. ;
  12. ;  written by Andy Hertzfeld  August, 1982
  13. ;
  14. ;  (c) 1982-1986 by Apple Computer, Inc.  All rights reserved.
  15. ;
  16. ;     This file contains the control definition procedure
  17. ;     that defines scrollBar-type dials.
  18. ;
  19. ;  Modification History:
  20. ;
  21. ;     29-Aug-82    AJH  Added "255" hiliting, non-rectangular indicators
  22. ;            to    ScrollBarProc
  23. ;     31-Aug-82    AJH  Added hysterisis to scrollBar, rounding to value calculations
  24. ;     19-Sep-82    AJH  Re-arranged ScrollBar proc, removed DragThumb
  25. ;     03-Oct-82    AJH  Fixed bug in scrollBar positioning -- wasn't ctl relative
  26. ;     10-Oct-82    AJH  Converted for QuickDraw Trap Interface
  27. ;     17-Oct-82    AJH  Made controlProcs preserve A1
  28. ;     07-Nov-82    AJH  Made wide scrollBars look better
  29. ;     11-Nov-82    AJH  fixed thumb scaling problem in CalcIBox (subtract min)
  30. ;     14-Nov-82    AJH  removed box in arrowBits
  31. ;     16-Nov-82    AJH  Made branch tables offset based
  32. ;     28-Dec-82    AJH  Put scrollBar definition proc in its own file
  33. ;     30-Dec-82    AJH  Changed hystersis for thumbDrag to 24 pixels
  34. ;     30-Jul-83    SC    Variant 1 for microsoft - no grey or elevator (Yuck)
  35. ;     04-Sep-83    AJH  Made it respond to message 8 (just a stub)
  36. ;     08-Oct-83    AJH  Changed rounding to fix "off by 1" bug
  37. ;     10-Nov-83    AJH  Changed disabling -- don't fill with gray
  38. ;     11-Nov-83    AJH  Made it redraw all if disabled
  39. ;     27-Dec-83    AJH  Made min=max act disabled; added "254" hiliting
  40. ;     13-Apr-84    SC    Replaced _EraseRgn    with _FillRgn,white
  41. ;     11-Jan-85    JTC  convert to MDS
  42. ;     14-Feb-85    JTC  named rsrc.
  43. ;     18-Apr-85    EHB  Eliminated useless framerects in DrawSBar
  44. ;     16-May-85    EHB  Only return "254" if point in control!
  45. ;     29-Jul-85    EHB  converted back to porkshop
  46. ;
  47. ;--Lonely Heiffer Release----------------------------------------------
  48. ;
  49. ;     28-Apr-86    DAF     Workshop->MPW, added color support for Reno
  50. ;<C203/06Oct86> DAF  Updated color support on nuMac to RGBColor
  51. ;<C529/14Dec86> DAF     Fixed a trashed register
  52. ;<C700/26Jan87> DAF     Universal defproc (Version 10)
  53.  
  54.  
  55.             BLANKS        ON
  56.             STRING        ASIS
  57.  
  58.             LOAD        'inc.sum.d'
  59.             LOAD        'nEqu.d'
  60.             INCLUDE        'colorEqu.a'
  61.  
  62. CDEF1        PROC        EXPORT
  63. ;
  64. ; FUNCTION ScrollBarProc( theControl: ControlHandle;
  65. ;              message:      INTEGER;
  66. ;              param:      LongInt): LongInt;
  67. ;
  68.  
  69.  
  70. ;  And a stack frame definition
  71.  
  72. SavePen         EQU  -20
  73. Align            EQU     -21                ;dead byte for alignment of stack frame
  74. IsColor            EQU     -22                ;is this a color system?
  75. IndicatorRect    EQU  -30
  76. AuxCtlHndl        EQU     -34                ;<DAF 28Apr86>
  77. AuxCtlPtr        EQU     -38                ;<DAF 28Apr86>
  78. SavFgCol        EQU     -44                ;<DAF 05Oct86>
  79. SavBkCol        EQU     -50                ;<DAF 05Oct86>
  80. TempCol            EQU     -56                ;<s557 d√b 08Aug88>
  81. FrameSize        EQU     -56                ;<s557 d√b 08Aug88>
  82. CtlHndl            EQU      14                ;<DAF 28Apr86>
  83.  
  84. ;
  85. ;  Here is the dispatch table for the scrollBar definition procedure, which implements
  86. ;  semi-Lisa style scrollBar type controls for the Mac toolBox.  It shares a common
  87. ;  dispatcher with the pushButton proc (see above)
  88. ;
  89.             BRA.S    @0
  90.  
  91.             DC.W     0
  92.             DC.B     'CDEF'
  93.             DC.W     1
  94.             DC.W     10                     ; version #
  95.  
  96. @0
  97.             LINK    A6,#FrameSize        ; set up a stack frame to address parameters
  98.             MOVEM.L D3-D6/A1-A4,-(SP)    ; save work registers
  99.  
  100. ; test if the message is in range
  101.  
  102.             CMP.W    #thumbCtlMsg,12(A6) ; compare to highest value
  103.             BGT     OORange                ; skip it, it's too high
  104.             CMP.W    #drawCtlMsg,12(A6)    ;  compare to lowest value, too
  105.             BMI     OORange                ;    
  106.  
  107. ;
  108. ; save the penState and set it our way
  109. ;
  110.             PEA     SavePen(A6)         ; push pointer to savePenState
  111.             _GetPenState                ; remember current penState
  112.             _PenNormal                    ; set the pen the way we    want it
  113.  
  114. ; Determine type of system.  We need to know if we have color QuickDraw and a color
  115. ;    window manager port.
  116.     
  117.             CMP.W    #$3FFF,ROM85        ; do we have color QD? 
  118.             SLS        IsColor(A6)            ; set boolean depending on color or B&W system
  119.             BHI.S    @BWSys                ; no, this system has B&W QD
  120.             
  121. ; save the current port's colors
  122.             
  123.             MOVE.L    GrafGlobals(A5),A0    ; get pointer to grafGlobals    <C407/16Nov86> DAF
  124.             MOVE.L    thePort(A0),A0        ; get pointer to thePort        <C407/16Nov86> DAF
  125.  
  126.             PEA        SavFgCol(A6)        ; save foreColor
  127.             _GetForeColor                ;
  128.             PEA        SavBkCol(A6)        ; save backColor too
  129.             _GetBackColor                ;
  130.  
  131. ;
  132. ; get the CtlAuxRec for this guy and lock it's colortable            <DAF 26Apr86>
  133. ;
  134.             CLR.L    -(SP)                ; return the handle here
  135.             CLR.B    -(SP)                ; space for boolean func return
  136.             MOVE.L    CtlHndl(A6),-(SP)    ; push the control handle
  137.             PEA        6(SP)                ; push a pointer to placeholder
  138.             _GetAuxCtl                    ; get its auxRec
  139.             ADDQ    #2,SP                ; don't need boolean result
  140.             MOVE.L    (SP)+,A0            ; get auxCtl handle
  141.             MOVE.L    (A0),A0                ; a pointer to the auxCtlRec
  142.             MOVE.L    ctlCTable(A0),A0    ; get colortable's handle
  143.             MOVE.L    A0,AuxCtlHndl(A6)    ; save the handle
  144.             _HLock                        ; lock the handle
  145.             MOVE.L    (A0),AuxCtlPtr(A6)    ; save a pointer
  146.             
  147. @BWSys
  148.  
  149. ;
  150. ; fetch the parameters into registers
  151. ;
  152.             LEA     8(A6),A0            ; get ptr to first parameter
  153.             MOVE.L    (A0)+,D3            ; get param in D3
  154.             MOVE.W    (A0)+,D0            ; get message
  155.             MOVE.L    (A0)+,A3            ; get the control handle
  156.             MOVE.W    (A0)+,D6            ; get selection index
  157.             CLR.L    (A0)                ; clear out function result
  158.             MOVE.L    (A3),A0             ; get control pointer in    A0
  159. ;
  160. ; case out on the message number
  161. ;
  162.             ADD     D0,D0                ; double for word index
  163.             LEA     GoScrollBar,A1        ; get table address
  164.             ADD     0(A1,D0),A1         ; compute dispatch address
  165.             JSR     (A1)                ; dispatch to appropriate routine
  166. ;
  167. ; restore original pen state
  168. ;
  169.             PEA     SavePen(A6)         ; push savePenState
  170.             _SetPenState                ; restore original pen state
  171.  
  172. ;
  173. ; clean up color stuff                                                <DAF 28Apr86>
  174. ;
  175.             TST.B    IsColor(A6)            ;
  176.             BEQ.S    @NoColor1            ; if on B&W, then skip
  177.  
  178.             MOVE.L    AuxCtlHndl(A6),A0    ; unlock the CDEF
  179.             _HUnlock
  180.             PEA        SavFgCol(A6)        ;
  181.             _RGBForeColor                ;
  182.             PEA        SavBkCol(A6)        ;
  183.             _RGBBackColor                ;
  184.             
  185. @NoColor1
  186.  
  187. ;
  188. ; we're done -- restore registers and return to caller
  189. ;
  190.  
  191. OORange                                    ; 'Out Of Range, of course'
  192.             MOVEM.L (SP)+,D3-D6/A1-A4    ; restore work registers
  193.             UNLK    A6                    ; unlink    stack frame
  194. TenBytExit    MOVE.L    (SP)+,A0            ; get return address
  195.             ADD     #12,SP                ; strip parameters
  196.             JMP     (A0)                ; return    to caller
  197.  
  198. GoScrollBar
  199.             DC.W     DrawSBar-GoScrollBar     ; draw is message 0
  200.             DC.W     HitSBar-GoScrollBar ; hit test is message 1
  201.             DC.W     CalcSBar-GoScrollBar     ; calc regions is message 2
  202.             DC.W     InitSBar-GoScrollBar     ; allocate indicator region (3)
  203.             DC.W     DispSBar-GoScrollBar     ; de-allocate indicator region (4)
  204.             DC.W     MoveSBar-GoScrollBar     ; message 5 is move indicator call (5)
  205.             DC.W     ThumbSBar-GoScrollBar     ; message 6 is thumb dragging
  206.  
  207. ;
  208. ;  16 wide by 16 high little bitMaps used for scrollBar arrows
  209. ;
  210. ;    (the comments as to which are left/right or up/down may lie)
  211. ;
  212.  
  213. ;
  214. ; Left Arrow BitMap
  215. ;
  216. LArrowData
  217.             DC.W     $FFFF,$8081,$80C1,$80A1,$8F91,$8809,$8805,$8803
  218.             DC.W     $8805,$8809,$8F91,$80A1,$80C1,$8081,$8001,$FFFF
  219. LArrowMask
  220.             DC.W     $FFFF,$8081,$80C1,$80E1,$8FF1,$8FF9,$8FFD,$8FFF
  221.             DC.W     $8FFD,$8FF9,$8FF1,$80E1,$80C1,$8081,$8001,$FFFF
  222.  
  223. ;
  224. ;  Right Arrow BitMap
  225. ;
  226. RArrowData
  227.             DC.W     $FFFF,$8101,$8301,$8501,$89F1,$9011,$A011,$C011
  228.             DC.W     $A011,$9011,$89F1,$8501,$8301,$8101,$8001,$FFFF
  229. RArrowMask
  230.             DC.W     $FFFF,$8101,$8301,$8701,$8FF1,$9FF1,$BFF1,$FFF1
  231.             DC.W     $BFF1,$9FF1,$8FF1,$8701,$8301,$8101,$8001,$FFFF
  232.  
  233. ;
  234. ; Up Arrow BitMap
  235. ;
  236. UArrowData
  237.             DC.W     $FFFF,$8001,$8001,$8FE1,$8821,$8821,$8821,$F83D
  238.             DC.W     $A009,$9011,$8821,$8441,$8281,$8101,$8001,$FFFF
  239. UArrowMask
  240.             DC.W     $FFFF,$8001,$8001,$8FE1,$8FE1,$8FE1,$8FE1,$FFFD
  241.             DC.W     $BFF9,$9FF1,$8FE1,$87C1,$8381,$8101,$8001,$FFFF
  242. ;
  243. ; Down Arrow BitMap
  244. ;
  245. DArrowData
  246.             DC.W     $FFFF,$8001,$8101,$8281,$8441,$8821,$9011,$A009
  247.             DC.W     $F83D,$8821,$8821,$8821,$8FE1,$8001,$8001,$FFFF
  248. DArrowMask
  249.             DC.W     $FFFF,$8001,$8101,$8381,$87C1,$8FE1,$9FF1,$BFF9
  250.             DC.W     $FFFD,$8FE1,$8FE1,$8FE1,$8FE1,$8001,$8001,$FFFF
  251.  
  252.  
  253.  
  254. ; SetUpColor takes a window part identifier in D0, finds the corresponding
  255. ;    part in the AuxWinTable (the part code is in the .value field) and returns
  256. ;    a pointer to its RGB on the stack.  If the requested part is not found,
  257. ;    the first color table element is used (I'd use frameColor, but that might
  258. ;    not be there!).  Trashes A0/D0.
  259.  
  260. SetUpColor
  261.             MOVE.L    D1,-(SP)            ; save a register
  262.             MOVE.L    AuxCtlPtr(A6),A0    ; get the color table pointer
  263.             MOVE.W    CTSize(A0),D1        ; get the color table size
  264.             MULU    #8,D1                ; convert to color table index
  265. LegalIndex    
  266.             CMP.W    CTTable+value(A0,D1),D0    ; is this the one?
  267.             BEQ.S    FoundIt                ; if equal, then done
  268.             SUB.W    #8,D1                ; try the previous one
  269.             BGE.S    LegalIndex            ; loop while index positive
  270.             MOVEQ    #0,D1                ; OK, use the first one
  271. FoundIt        
  272.             LEA        CTTable+rgb(A0,D1),A0 ; get the address of the color to use
  273.             MOVE.L    A0,D0                ; we'll need A0 in a second
  274.             MOVE.L    (SP)+,D1            ; restore the register
  275.             MOVE.L    (SP)+,A0            ; get the return address
  276.             MOVE.L    D0,-(SP)            ; push the rgb addr on the stack
  277.             JMP        (A0)                ; return to caller
  278.             
  279.             
  280. ;
  281. ; DrawSBar draws a scroll bar as specified by the controlHandle in A3. D3 has the
  282. ; desired "hilite" area code.
  283. ;
  284. DrawSBar
  285.  
  286. ;
  287. ; Set up fore- and backcolors (since they rarely change)
  288. ;        {this could almost happen in the prologue!}
  289. ;
  290.  
  291.             TST.B    IsColor(A6)            ; are we on a color system?
  292.             BEQ.S    @NoColor2            ; if on B&W, then skip
  293.             
  294.             MOVEQ    #cFrameColor,D0        ; get the index of the color to set
  295.             BSR.S    SetUpColor            ; get this color on the stack
  296.             _RGBForeColor                ; and set it
  297.             MOVEQ    #cBodyColor,D0        ;
  298.             BSR.S    SetUpColor            ;
  299.             _RGBBackColor
  300.  
  301.             MOVE.L    (A3),A0             ; get control pointer in A0 again since color calls killed it <C529/14Dec86> DAF
  302.             
  303. @NoColor2                                ; END OF A COLOR-ONLY SECTION
  304.  
  305. ;
  306. ; Figure out if the scroll bar is horizontal or vertical and handle each
  307. ; case separately. see if its more horizontal or vertical -- A0 points to the
  308. ; rect to be tested.  D0 returns 0 to select vertical and two to select horizontal.
  309. ; After we know which axis, draw the arrows.
  310. ;
  311.             TST.B    ContrlVis(A0)        ; is it visible?
  312.             BEQ     StubSBar            ; if not, don't draw
  313.  
  314. ; if it was disabled, draw the whole thing
  315.  
  316.             CMP.B    #$FF,D3             ; disabled part code?
  317.             BNE.S    @0                    ; if not, skip
  318.             MOVEQ    #0,D3                ; if so,    draw all
  319. @0
  320.             MOVE.B    ContrlHilite(A0),D4 ; get current hilite in register
  321.             BSR     GetTCtlRect         ; copy the control rect into tempRect
  322.             BSR     TestHV                ; get horizontal/vertical index in D0
  323. ;
  324. ; adjust for 1st arrow (if we're supposed to)
  325. ;
  326.             MOVE.W    Top(A1,D0),D1        ; get vertical coordinate
  327.             ADD     D2,D1                ; compute bottom
  328.             MOVE.W    D1,Bottom(A1,D0)    ; update    bottom
  329.             LEA     RArrowData,A1        ; point to right    arrow bitMap
  330.             MOVEQ    #inUpButton,D1        ; signal    1st arrow
  331. ;
  332.             MOVEM    D0/D2,-(SP)         ; remember hv selector
  333. ;
  334.             BSR.S    ShouldIDraw         ; test hilite to see if we should draw
  335.             BNE.S    SkipUp
  336.             BSR     DrawArrowBox        ; draw the arrow box
  337. ;
  338. ; now do the other arrow
  339. ;
  340. SkipUp
  341.             BSR     GetTCtlRect         ; copy bounding rect into tempRect
  342.             MOVEM    (SP)+,D0/D2         ; restore hv selector
  343. ;
  344. ; adjust rect for 2nd arrow
  345. ;
  346.             MOVE    Bottom(A1,D0),D1    ; get bottom coordinate
  347.             SUB     D2,D1                ; compute top
  348.             MOVE    D1,Top(A1,D0)        ; adjust    box top
  349.             LEA     LArrowData,A1        ; point to 1st set of bitMaps
  350.             MOVEQ    #inDownButton,D1    ; signal    in 2nd arrow
  351. ;
  352.             BSR.S    ShouldIDraw         ; dont't    draw if we done have to
  353.             BNE.S    SkipDown
  354.             BSR     DrawArrowBox        ; draw the arrow    box
  355.  
  356. ;
  357. ; paint the body of the scrollBar light gray
  358. ;
  359. SkipDown
  360. ;
  361.             CMP     #1,D6                ; flavor one has no grey
  362.             BEQ     FrameCtl
  363.  
  364.             MOVE.W    #inThumb,D1         ; get thumb part code
  365.             BSR.S    ShouldIDraw         ; draw it?
  366.             BNE.S     StubSBar            ; don't need to frame scrollbar    <EHB 4-18-85>
  367.  
  368.             BSR     GetTCtlRect         ; get control bounding rectangle
  369.             MOVE.L    A1,-(SP)            ; push tempRect
  370.             BSR     GetLtGray            ; get pointer to light gray pattern
  371.             MOVE.L    A0,-(SP)            ; push it
  372. ;
  373.             BSR.S    IsDisabled            ; is it disabled?
  374.             BNE.S    @0                    ; if not, skip
  375.  
  376.             MOVE.L    (A5),A0             ; get grafGlobals
  377.             LEA     White(A0),A0        ; get address of white pattern
  378.             MOVE.L    A0,(SP)             ; use it
  379. @0
  380.             LEA     TempRect,A1         ; get tempRect pointer back
  381.             MOVE.L    A1,A0                ; put in A0 for TestHV
  382.             BSR.S    TestHV                ; get h/v index
  383.             SWAP    D2                    ; get width in high part
  384.             MOVE.W    #1,D2                ; get 1 in low part
  385.             TST.W    D0                    ; which dimension?
  386.             BEQ.S    @1                    ; skip correction if vertical
  387.  
  388.             SWAP    D2
  389.  
  390. @1            MOVE.L    A1,-(SP)            ; push a pointer to the rectangle
  391.             MOVE.L    D2,-(SP)            ; push inset factor
  392.  
  393.             _InsetRect                    ; inset it appropriately
  394.             _FillRect                    ; paint the body gray
  395.             BRA.S    DoIndicator         ; go plot the indicator
  396. ;
  397. ; Utility ShouldIDraw -- to test when to skip drawing a part of the scrollBar.
  398. ; On entry, D3 has parameter indicating part that needs drawing while D1 holds
  399. ; the part we are about to draw.  If D3 is zero, always draw it.  Otherwise,
  400. ; draw only if it matches.    Returning 0 in the Z-flag means you should draw
  401. ;
  402. ShouldIDraw
  403.             TST     D3                    ; examine the parameter
  404.             BEQ.S    StubSBar            ; its zero so don't test    further
  405.             CMP     D1,D3                ; the right part
  406. StubSBar    RTS                         ; the z-flag has    the answer
  407.  
  408. ; IsDisabled is a utility to check to see if a scrollBar is disabled or not.
  409. ; It returns with the z-flag set if it is disabled
  410.  
  411. IsDisabled
  412.             MOVE.L    (A3),A0             ; get sBar pointer
  413.             MOVE.B    ContrlHilite(A0),D0 ; get the hilite    parameter
  414.  
  415.             ADDQ.B    #1,D0                ; was it    255?
  416.             BEQ.S    @0                    ; if so,    its disabled
  417.             ADDQ.B    #1,D0                ; how about 254?
  418.             BEQ.S    @0                    ; if so,    its disabled also
  419.  
  420.             MOVE.W    ContrlMin(A0),D0    ; get the min
  421.             CMP.W    ContrlMax(A0),D0    ; same as the max?
  422. @0
  423.             RTS                         ; return    to caller with z-flag result
  424.  
  425. ;
  426. ; Check the hilite state.  If the control is inactive (hilite = 255), don't draw
  427. ; the indicator at all.
  428. ;
  429. DoIndicator
  430.             
  431.             TST.B    IsColor(A6)            ; are we on a color system?
  432.             BEQ.S    @NoColor3            ; if on B&W, then skip
  433.             
  434.             MOVEQ    #cElevatorColor,D0    ; set up this as the background color <DAF 28Apr86>
  435.             BSR        SetUpColor            ;
  436.             _RGBBackColor
  437. @NoColor3                                ; END OF A COLOR-ONLY SECTION
  438.  
  439.             BSR     CalcIBox            ; calculate the indicator box
  440.             BSR.S    IsDisabled
  441.             BEQ.S    FrameCtl            ; if so,    skip
  442.  
  443.             MOVE.L    ContrlData(A0),-(SP)    ; push indicator    region handle
  444.             MOVE.L    (SP),-(SP)            ; we need it again
  445.             MOVE.L    GrafGlobals(A5),A0    ; our erase rect
  446.             PEA     white(A0)
  447.             _FillRgn                    ; paint it white
  448.             _FrameRgn                    ; and frame it
  449. ;
  450. ; frame the whole rect
  451. ;
  452. FrameCtl
  453.             TST.B    IsColor(A6)            ; if not in color...            <s557 d√b 08Aug88>
  454.             BEQ.S    @NoColor4            ;                                <s557 d√b 08Aug88>
  455.             PEA        TempCol(A6)            ; Avoid QD's contrast mapping    <s557 d√b 08Aug88>
  456.             MOVE.L    (SP),-(SP)            ; by explicitly having the same    <s557 d√b 08Aug88>
  457.             _GetForeColor                ; background and foreground.    <s557 d√b 08Aug88>
  458.             _RGBBackColor                ;                                <s557 d√b 08Aug88>
  459. @NoColor4                                ;                                <s557 d√b 08Aug88>
  460.  
  461.             MOVE.L    (A3),A0
  462.             PEA     ContrlRect(A0)        ; push pointer to scrollBar rect
  463.             _FrameRect                    ; frame it
  464. ;
  465. ; all done drawing the scroll bar
  466. ;
  467.             RTS
  468.  
  469. ;
  470. ; TestHV is a utility that determines if the rectangle pointed to by A0 is more horizontal
  471. ; or vertical.    Return 0 in D0 if its more vertical and 2 if its more horizontal.
  472. ; This routine trashes D1.    The result is also reflected in the condition code.
  473. ; It also returns the width/height of the minor dimension in D2.
  474. ;
  475. TestHV
  476.             MOVE    Bottom(A0),D0
  477.             SUB     Top(A0),D0            ; get height
  478.             MOVE    Right(A0),D1
  479.             SUB     Left(A0),D1         ; get width
  480.  
  481.             CMP     D0,D1                ; compare width and height
  482.             BGT.S    @1                    ; branch    it width is greater
  483.  
  484.             MOVE    D1,D2                ; horizontal in D2
  485.             MOVEQ    #0,D0                ; signal    its vertical
  486.             RTS
  487.  
  488. @1            MOVE    D0,D2                ; vertical in D2
  489.             MOVEQ    #2,D0                ; signal    its horizontal
  490.             RTS
  491. ;
  492. ;  DrawArrowBox is a routine that clears and frames an arrow box and then blits
  493. ;  across the appropriate arrow (looks at hilite state).  On entry, TempRect has the
  494. ;  box for the arrow, D0 has h/v selector, D1 has left/right selector,A1 points to the
  495. ;  arrow bitMap, A3 has the control handle.
  496. ;
  497. DrawArrowBox
  498.             MOVE.L    (A3),A0             ; get the control pointer
  499.             CMP.B    ContrlHilite(A0),D1 ; should    it be hilited?
  500.             BNE.S    @1                    ; if not, skip
  501.             ADD     #32,A1                ; if so,    bump to hilite mask
  502. ;
  503. ; adjust bitMap for vertical or horizontal arrows
  504. ;
  505. @1            TST     D0
  506.             BNE.S    @2
  507.             ADD     #128,A1             ; bump to horizontal
  508. ;
  509. ; plot the arrow
  510. ;
  511. @2            CLR     D0                    ; mode is srcCopy
  512.             BSR.S    PlotSymbol            ; plot the bitmap in the tempRect box
  513. ;
  514. ; Now frame the box and we're done! (bitmap has rect EHB)
  515. ;
  516. ;            PEA     TempRect            ; push the rectangle            <EHB 4-18-85>
  517. ;            _FrameRect                    ; frame it and we're done       <EHB 4-18-85>
  518. SBarStub
  519.             RTS
  520. ;
  521. ;  PlotSymbol -- plot the little 16 by 16 symbol bitmap pointed to by A1 into the rectangle
  522. ;  pointed held in TempRect. D0 holds the mode.
  523. ;
  524. PlotSymbol
  525.             LEA     IconBitMap,A0        ; get pointer to source bitmap
  526.             MOVE.L    A1,(A0)+            ; update base address of bitMap
  527.             MOVE    #2,(A0)+            ; update rowBytes
  528.             CLR.L    (A0)+                ; topLeft is zero, zero
  529.             MOVE.L    #$00100010,(A0)     ; adjust boundsRect
  530. ;
  531. ; push parameters for CopyBits call to transfer arrow bitMap
  532. ;
  533.             PEA     IconBitMap            ; push pointer source bitmap
  534.             MOVE.L    (SP),A0             ; remember in A0, too
  535.             MOVE.L    GrafGlobals(A5),A1        ; get lisaGraf global baseaddress
  536.             MOVE.L    THEPORT(A1),A1        ; get thePort
  537.             PEA     PORTBITS(A1)        ; that's    the destination bitmap
  538. ;
  539.             PEA     BOUNDS(A0)            ; boundsRect of bitmap is source
  540.             PEA     TempRect            ; tempRect is the destination
  541.             MOVE.W    D0,-(SP)            ; theMode is in D0
  542.             CLR.L    -(SP)                ; no mask region
  543. ;
  544. ; transfer the bitMap (stretching as necessary...)
  545. ;
  546.             _CopyBits                    ; let Bill stretch those    bits
  547.             RTS                         ; return    to caller
  548. ;
  549. ; CalcIBox is the crucial routine that computes the position of the top/left of the
  550. ; thumb by scaling the control's value according to its range and the screen area.
  551. ; Return the rectangle in IndicatorRect(A6).  It expects that A3 will hold the
  552. ; control handle as usual
  553. ;
  554. CalcIBox
  555.             MOVE    D3,-(SP)            ; preserve D3
  556.             LEA     IndicatorRect(A6),A1    ; get address of    indicator rectangle
  557.             BSR.S    GetCtlRect            ; first set it to control bounding rect
  558. ;
  559.             MOVEQ    #0,D1                ; clear out high    part of D1
  560.             MOVE.L    (A3),A0             ; get pointer to    control
  561.             LEA     ContrlRect(A0),A0    ; get pointer to    the bounding rectangle
  562.             BSR.S     TestHV                ; get h/V selector index    in D0
  563.                                         ; ???? was .S
  564.             MOVE    D2,D3                ; keep minor dimension in D3
  565. ;
  566. ; compute control screen area in relevant dimension
  567. ;
  568.             MOVE    Bottom(A0,D0),D1    ; get logical "bottom"
  569.             SUB     Top(A0,D0),D1        ; compute "height"
  570.             SUB     D2,D1                ; discount arrow    box
  571.             SUB     D2,D1                ; discount other    one, too
  572.             SUB     D2,D1                ; and the indicator
  573. ;
  574. ; compute "screenSize times value"
  575. ;
  576.             MOVE.L    (A3),A0             ; get control pointer
  577.             MOVE.W    ContrlValue(A0),D2    ; get current value
  578.             SUB.W    ContrlMin(A0),D2    ; get delta from    min
  579.             MULU    D2,D1                ; compute value*screensize
  580. ;
  581. ; compute size of logical space
  582. ;
  583.             MOVE    ContrlMax(A0),D2    ; get max
  584.             SUB     ContrlMin(A0),D2    ; compute size of space
  585.             BEQ.S    Scale0                ; dont divide by    0
  586. ;
  587. ; perform the scaling
  588. ;
  589.             DIVU    D2,D1                ; compute where iBox should go
  590.             BSR     RoundOff            ; round off D1
  591.             ADD     D3,D1                ; skip over arrow box
  592. ;
  593. ; update indicator rect to correct position
  594. ;
  595. UpdateIRect
  596.             LEA     IndicatorRect(A6),A1    ; get pointer to    rect
  597.             ADD     Top(A1,D0),D1        ; compute the logical "top"
  598.             MOVE    D1,Top(A1,D0)        ; update    it
  599.             ADD     D3,D1                ; bump to "bottom"
  600.             MOVE    D1,Bottom(A1,D0)    ; update    "bottom"
  601. ;
  602.             EOR     #2,D0                ; flip to minor dimension
  603.             ADDQ    #1,Top(A1,D0)        ; inset logical "left"
  604.             SUBQ    #1,Bottom(A1,D0)    ; inset logical "right"
  605. ;
  606. ; set up the indicator region
  607. ;
  608.             MOVE.L    ContrlData(A0),-(SP)    ; push indicator    region handle
  609.             MOVE.L    A1,-(SP)            ; push rect ptr
  610.             _RectRgn                    ; make a    rectangular region
  611. ;
  612. CalcIDone    MOVE    (SP)+,D3            ; restore D3
  613.             RTS
  614. ;
  615. ; if min = max, pin at top
  616. ;
  617. Scale0        MOVE    D3,D1
  618.             BRA.S    UpdateIRect
  619. ;
  620. ; GetCtlRect is a code saving utility that copies the bounding rectangle of the control
  621. ; whose handle is in A3 into the rectangle pointed to by A1.  This routine blows
  622. ; A0 but preserves A1. GetTCtlRect is an alternative entry used to save code
  623. ;
  624. GetTCtlRect LEA     TempRect,A1
  625. GetCtlRect    MOVE.L    (A3),A0             ; get pointer to    control
  626.             LEA     ContrlRect(A0),A0    ; get pointer to    bounding rect
  627.             MOVE.L    (A0),(A1)            ; copy topLeft
  628.             MOVE.L    4(A0),4(A1)         ; copy botRight
  629. NoSBarHit
  630.             RTS
  631. ;
  632. ; HitSBar is the hit test routine for the scroll bar definition routine.  It classifies
  633. ; the position of the mouse passed in D3
  634. ;
  635. HitSBar
  636.             MOVE.B    ContrlHilite(A0),D4 ; get hilite state        <EHB 16-May-85
  637.             CMP.B    #254,D4             ; 254 hiliting?         <EHB 16-May-85>
  638.             BEQ.S    @0                    ; => yes, do hit-test    <EHB 16-May-85>
  639.  
  640.             BSR     IsDisabled            ; otherwise disabled?    <EHB 16-May-85>
  641.             BEQ.S    NoSBarHit            ; => yes, return with 0 <EHB 16-May-85>
  642. @0
  643.             LEA     ContrlRect(A0),A4    ; keep rect pointer in A4
  644.             CLR.W    -(SP)                ; make room for function result
  645.             MOVE.L    D3,-(SP)            ; push the point
  646.             MOVE.L    A4,-(SP)            ; push address of rect
  647.             _PtInRect                    ; in the    rectangle?
  648.             TST.B    (SP)+                ; examine result
  649.             BEQ.S    NoSBarHit            ; if not, we're done
  650.  
  651. ; check for 254 hiliting
  652.  
  653.             ADDQ.B    #2,D4                ; 254 hiliting?         <EHB 16-May-85>
  654.             BEQ.S    Return254            ; => yes, return 254    <EHB 16-May-85>
  655.  
  656. ; its in the rect, so classify if in upButton,downButton,pageUp,pageDown or thumb
  657.  
  658.             BSR.S    NormalizePt         ; swap relevant coordinate into low part
  659. ;                                        ; and set up D0,D2
  660. ; see if its in the top button
  661. ;
  662. @1            MOVE    D3,D1                ; get copy of mousePoint
  663.             SUB     0(A4,D0),D1         ; subtract rectangle top
  664.             CMP     D2,D1                ; is it within width of the top?
  665.             BGT.S    @2                    ; it not, go check bottom
  666.             MOVEQ    #inUpButton,D0        ; classify it
  667.             BRA.S    UpdateResult        ; all done
  668. ;
  669. ; see if its in the bottom button
  670. ;
  671. @2            MOVE    4(A4,D0),D1         ; get bottom
  672.             SUB     D3,D1                ; get distance from bottom
  673.             CMP     D2,D1                ; is it in it?
  674.             BGT.S    CheckInd            ; if not, go check indicator
  675. ;
  676.             MOVEQ    #inDownButton,D0
  677. UpdateResult
  678.             MOVE    D0,22(A6)            ; return    result
  679.             RTS
  680. Return254
  681.             MOVE    #254,D0
  682.             BRA.S    UpdateResult
  683. ;
  684. ; its not in either button so it must be the thumb or one of the page areas.  Check
  685. ; for the thumb first
  686. ;
  687. CheckInd
  688.             CMP     #1,D6                ; for flavor one don't test
  689.             BEQ.S    NoSBarHit
  690.  
  691.             BSR     CalcIBox            ; calculate the indicator rectangle
  692.             BSR.S    NormalizePt         ; restore back to normal    point
  693.             CLR.W    -(SP)                ; make space for    boolean result
  694.             MOVE.L    D3,-(SP)            ; push the point
  695.             MOVE.L    (A3),A0
  696.             MOVE.L    ContrlData(A0),-(SP)    ; push the indicator region
  697.             _PtInRgn                    ; is the    mouse in the indicator?
  698.             TST.B    (SP)+                ; (..the    suspense builds...)
  699.             BEQ.S    CheckPage            ; branch    if its not in the indicator
  700. ;
  701. ; its in the thumb so report that to the application
  702. ;
  703.             MOVE    #inThumb,D0         ; get result
  704.             BRA.S    UpdateResult        ; all done -- go    update result
  705.  
  706. ;
  707. ; it must be in one of the two page areas.    Determine which one by looking at the
  708. ; midPoint of the indicator's bounding rectangle.
  709. ;
  710. CheckPage
  711.             BSR.S    NormalizePt         ; normalize (get    interesting low word)
  712.             MOVE.L    (A3),A0             ; get control pointer
  713.             MOVE.L    ContrlData(A0),A0    ; get region handle
  714.             MOVE.L    (A0),A0             ; get region pointer
  715.             LEA     RgnBBox(A0),A0        ; point to the region bounding box
  716. ;
  717. ; determine midpoint
  718. ;
  719.             MOVE    Bottom(A0,D0),D1    ; get logical bottom
  720.             SUB     Top(A0,D0),D1        ; get logical height
  721.             LSR     #1,D1                ; divide    by 2
  722.             ADD     Top(A0,D0),D1        ; add to    get the midpoint
  723. ;
  724. ; at this point, D1 has the midpoint in the important dimension.  Compare with the
  725. ; mouse point to decide if its page up or down.
  726. ;
  727.             CMP     D1,D3                ; compare mousePt with midPoint
  728.             BLT.S    PageItUp            ; if above its the logical "top"
  729.             MOVEQ    #inPageDown,D0        ; set result code
  730.             BRA.S    UpdateResult        ; all done -- go    update result
  731. PageItUp    MOVEQ    #inPageUp,D0        ; set result code
  732.             BRA.S    updateResult        ; all done
  733. ;
  734. ; NormalizePt takes a rect pointer in A4 and a point in D3 and swaps the points
  735. ; coordinates according to the relevant dimensions
  736. ;
  737. NormalizePt
  738.             MOVE.L    A4,A0                ; get rect pointer in A0
  739.             BSR     TestHV                ; get horizontal    vertical offset
  740.             BNE.S    @1                    ; if horizontal,    skip
  741.             SWAP    D3                    ; its vertical so get y in low part
  742. @1            RTS                         ; all done
  743.  
  744. ;
  745. ; CalcSBar returns the bounding region of the scroll bar.  D3 holds the region parameter.
  746. ; If the high bit of D3 is set, return the indicator region, other return the entire
  747. ; bounding region
  748. ;
  749. CalcSBar
  750.             TST.L    D3                    ; indicator or body?
  751.             BMI.S    GetIndRgn            ; if negative, go get indicator
  752.             MOVE.L    D3,-(SP)            ; push the region handle
  753.             PEA     ContrlRect(A0)        ; push rectangle    pointer
  754.             _RectRgn                    ; return    a rectangular region
  755.             RTS                         ; all done!
  756. ;
  757. ; the indicator region was requested so copy the one in the dataHandle
  758. ;
  759. GetIndRgn
  760.             BSR     CalcIBox            ; calculate indicator region
  761.             MOVE.L    (A3),A0             ; get pointer to    control
  762.             MOVE.L    ContrlData(A0),-(SP)    ; push indicator    region
  763.             MOVE.L    D3,-(SP)            ; push result region
  764.             CLR.B    (SP)                ; clear out high    byte
  765.             _CopyRgn                    ; clone the region
  766. ;
  767. ; set the pattern for dragging
  768. ;
  769.             BSR.S    GetLtGray            ; get pointer to    light gray
  770.             MOVE.L    (A0)+,DragPattern    ; update    the drag pattern
  771.             MOVE.L    (A0),DragPattern+4    ; update    the drag pattern
  772.             RTS
  773. ;
  774. ; GetLtGray is a short utility that get a pointer to a lightGray pattern from
  775. ; the resource manager.
  776. ;
  777. GetLtGray
  778.             SUBQ    #4,SP                ; make room for result
  779.             MOVE.W    #SBarPatID,-(SP)    ; push resource ID
  780.             _GetPattern                 ; get the pattern
  781.             MOVE.L    (SP)+,A0            ; get pattern handle
  782.             MOVE.L    (A0),A0             ; get pattern ptr
  783.             RTS
  784.  
  785. ;
  786. ;  handle the "position yourself" message by calling figuring out the new value and
  787. ;  calling SetCtlValue.  D3 holds the amount to move by.
  788. ;
  789. MoveSBar
  790.             MOVE.L    ContrlData(A0),A0    ; get handle of indicator region
  791.             MOVE.L    (A0),A0             ; get a pointer to it
  792.             LEA     RgnBBox(A0),A4        ; get pointer to    the bounding rect
  793. ;
  794. ; figure out new position by adding topLeft of current position to offset
  795. ;
  796.             ADD     Left(A4),D3         ; add the x coordinates
  797.             SWAP    D3                    ; get y in low word
  798.             ADD     Top(A4),D3            ; add the y coordinates
  799. ;
  800. ; select the relevant dimension and get it into the low word of D3
  801. ;
  802.             MOVE.L    (A3),A0             ; get the control pointer
  803.             LEA     ContrlRect(A0),A0    ; get the bounding rectangle
  804.             BSR     TestHV                ; get h/v index
  805.             BEQ.S    @1                    ; if its    y, we're cool
  806.             SWAP    D3                    ; get x into D3
  807. ;
  808. ; determine amount of screen area devoted to the scrollBar
  809. ;
  810. @1            SUB     Top(A0,D0),D3        ; make size ctl-relative
  811.             SUB     D2,D3                ; subtract arrow    offset
  812. ;
  813.             MOVE    Bottom(A0,D0),D1    ; get logical bottom
  814.             SUB     Top(A0,D0),D1        ; compute logical height
  815.  
  816.             SUB     D2,D1                ; compute active    area
  817.             SUB     D2,D1
  818.             SUB     D2,D1
  819.             MOVE    D1,D2                ; get answer in D2
  820. ;
  821. ; compute range of logical values: controlMax - controlMin
  822. ;
  823.             MOVE.L    (A3),A0             ; get control pointer
  824.             MOVE    ContrlMax(A0),D1    ; get max value
  825.             SUB     ContrlMin(A0),D1    ; compute range
  826. ;
  827. ; compute position*logical range/physical range
  828. ;
  829.             MULU    D3,D1                ; D3 has    current position
  830.             DIVU    D2,D1                ; divide    by physical range
  831.             BSR.S    RoundOff            ; round to nearest integer
  832. ;
  833. ; at this point D1 has the value so set it, after offsetting by the minimum
  834. ;
  835.             ADD.W    ContrlMin(A0),D1    ; offset    by minimum
  836.             MOVE.L    A3,-(SP)            ; push control handle
  837.             MOVE.W    D1,-(SP)            ; push the new value
  838.             _SetCtlValue                ; go set    the new value
  839.             RTS                         ; all done!
  840. ;
  841. ; InitSBar gets called when the scroll bar is allocated.  It allocates an empty region
  842. ; to use as the indicator region
  843. ;
  844. InitSBar    SUBQ    #4,SP
  845.             _NewRgn                     ; get a new region on the stack top
  846.             MOVE.L    (A3),A0             ; get control pointer
  847.             MOVE.L    (SP)+,ContrlData(A0)    ; remember new region in    control data
  848.             RTS
  849. ;
  850. ; DispSBar de-allocates the region used for the indicator
  851. ;
  852. DispSBar    MOVE.L    ContrlData(A0),A0    ; get handle of indicator region
  853.             _DisposHandle                ; dispose of it
  854.             RTS
  855. ;
  856. ; Utility RoundOff -- RoundOff the number in D1 to the nearest integer.  The remainder
  857. ; from dividing by D2 is in the high part of the word.
  858. ;
  859. RoundOff    MOVE.W    D0,-(SP)            ; preserve D0
  860.             MOVE    D2,D0                ; get old divisor
  861.             LSR     #1,D0                ; divide    by 2
  862.             SWAP    D1                    ; get remainder
  863.             CMP     D0,D1                ; compare remainder with    1/2 divisor
  864.             BLE.S    TruncateIt            ; if smaller, we're done
  865.             SWAP    D1                    ; get normal D1 back
  866.             ADDQ    #1,D1                ; round up
  867. ;
  868. RoundDone
  869.             MOVE.W    (SP)+,D0            ; restore D0
  870.             RTS
  871. ;
  872. ;  no need to round up so just truncate it
  873. ;
  874. TruncateIt
  875.             SWAP    D1                    ; restore quotient
  876.             BRA.S    RoundDone            ; all done with roundOff
  877.  
  878. ;
  879. ; ThumbSBar receives the "drag thumb message for the scroll bar.  On entry, D3 points
  880. ; to a structure that contains the starting point, it returns with pointers to
  881. ; the bounds and slopRect and the axis parameter
  882. ;
  883. ; Local Variable Equates
  884. ;
  885. BRect        EQU      0                     ; boundsRect
  886. SRect        EQU      8                     ; slopRect
  887. TAxis        EQU      16                  ; axis
  888. ;
  889. ThumbSBar
  890.             MOVE.L    D3,A4                ; keep pointer to parameter block
  891.             MOVE.L    (A4),D3             ; get the mouse point
  892. ;
  893.             LEA     BRect(A4),A2        ; get pointer to    boundsRect
  894.             MOVE.L    A2,A1                ; get pointer in    A1
  895.             BSR     GetCtlRect            ; copy control bounds rect
  896. ;
  897.             MOVE.L    A2,A0                ; point to boundsRect
  898.             BSR     TestHV                ; get h/v selector in D0
  899.             MOVE    D2,-(SP)            ; preserve D2
  900.             SWAP    D2
  901.             MOVE.W    #$FFE8,D2            ; get inset factor (24 pixels hyst)
  902.             MOVE    D0,D4                ; keep selector in D4
  903.             BEQ.S    @1                    ; if vertical, we're cool
  904.             SWAP    D2                    ; adjust    inset factor
  905.             BRA.S    @2
  906. ;
  907. @1            SWAP    D3                    ; adjust    mouse pt
  908. ;
  909. @2            MOVE.L    A2,-(SP)            ; push pointer to rectangle
  910.             MOVE.L    D2,-(SP)            ; push inset factor
  911.             _InsetRect                    ; go inset it
  912. ;
  913. ; build the slopRect by insetting the boundsRect
  914. ;
  915.             LEA     SRect(A4),A0        ; get slopRect pointer
  916.             MOVE.L    (A4),(A0)            ; copy boundsRect into slopRect
  917.             MOVE.L    4(A4),4(A0)         ; copy botRight,    too
  918. ;
  919.             MOVE.L    #$FF800000,D0        ; get inset factor (assume vertical)
  920.             TST     D4                    ; which dimension
  921.             BEQ.S    @3                    ; if vertical, we're cool
  922.             SWAP    D0
  923. ;
  924. @3            MOVE.L    A0,-(SP)            ; push slopRect pointer
  925.             MOVE.L    D0,-(SP)            ; push inset factor
  926.             _InsetRect                    ; inset it
  927. ;
  928. ; now further adjust the boundsRect depending where the mousePt is relative to the
  929. ; indicator box.
  930. ;
  931.             MOVE.L    (A3),A0             ; get control pointer
  932.             MOVE.L    ContrlData(A0),A0    ; get region handle
  933.             MOVE.L    (A0),A0             ; get region pointer
  934.             SUB     RgnBBox(A0,D4),D3    ; subtract relevant coordinate
  935.             ADD     D3,Top(A2,D4)        ; offset    logical top
  936. ;
  937. ; fix up logical bottom, too
  938. ;
  939.             MOVE    (SP)+,D2            ; get back D2
  940.             SUBQ    #1,D2
  941.             SUB     D2,Bottom(A2,D4)
  942.             ADD     D3,Bottom(A2,D4)    ; subtract (15-number) from bottom
  943. ;
  944. ; now set up axis parameter
  945. ;
  946.             LSR     #1,D4                ; divide    by 2
  947.             EOR     #1,D4                ; flip the sense
  948.             ADDQ    #1,D4                ; add increment
  949.             MOVE    D4,TAxis(A4)        ; to derive axis    parameter
  950.             RTS
  951.  
  952.  
  953.             END